**Recent Changes**

This chapter lists recent changes to lint that affect lint check
authors: new features, API and behavior changes, and so on. For
information about user visible changes to lint, see the User
Guide.

**8.8**

* For the string-replacement quickfix, you can now specify
  regex flags (such as Pattern.DOT_ALL) to change the pattern
  matching behavior.

**8.7**

* The unit testing support now checks to make sure that you
  don't have duplicate class names across Java and Kotlin
  (which can lead to subtle and confusing errors.)
* The `build.gradle.kts` unit testing support (`TestFiles.kts()`)
  now performs the same mocking of the builder model that the
  corresponding Groovy Gradle support (`Testfiles.gradle()`)
  performs. Among other things, this means that the other
  source files (`java()`, `kotlin()`, etc) must be located in
  source sets, e.g. `src/main/res/` and `/src/main/java/`
  rather than just `res/` and `src/`. This happens automatically
  if you don't manually specify a target path in the test file
  declaration.

**8.6**

* UAST repeats @JvmOverloaded methods in the AST. Lint now looks for
  and skips these duplications, and a new test mode also looks for
  potential problems in third party checks.
* Added a new chapter to the api-guide on AST analysis, and in
  particular, using the Kotlin Analysis API.
* The `UElementHandler` now supports recently added UAST element
  types: `UPatternExpression` and `UBinaryExpressionWithPattern`.
* There's a new test mode checking for issues related to
  `@JvmOverloads`. See the [test modes](test-modes.md.html) chapter
  for more.

**8.4**

* You can now use `~~` in text messages (error messages, issue
  explanations, etc) to create strikethrough text. For example, “`Don't
  do this: ~~super.onCreate()~~`” will render as “Don't do this:
  ~~super.onCreate()~~”.

**8.3**

* If you'd like to change your error message reported by your
  detector, you can now override your `Detector`'s `sameMessage`
  method: match the details in the previous error message with the
  new format. This is used by the baseline mechanism such that your
  message change doesn't suddenly invalidate all existing baseline
  files for your issue.

* The replace-string quickfix descriptor now lets you replace a string
  repeatedly. Example:
  ```
  fix().replace().text("Foo").with("Bar").repeatedly().build()
  ```

  You can also match an element optionally. Example:
  ```
  fix().composite(
    fix().replace().text("<Tag>").with("<tag>").build(),
     fix().replace().text("</Tag>").with("</tag>").optional().build()
  )
  ```

* The quickfix machinery was improved significantly. It now does a
  better job inserting imports (in alphabetical order instead of always
  prepending to the import list), inserting new XML attributes in the
  right canonical Android order, cleaning up whitespace after edits,
  etc. This may result in some diffs in any quickfix-related unit tests
  (e.g. `lint().run().expectFixDiffs(...)`)

* The `getFileNameWithParent` utility method now always uses / as
  a file separator instead of the platform-specific one (e.g. \ on
  Windows). This ensures that baselines don't vary their error
  messages (where this utility method is typically used) based on
  which OS they were generated on.

**8.2**

* For unit tests, you can now specify the language level to be used
  for Kotlin and Java. For example, if your unit test is using Java
  records, add `.javaLanguageLevel("17")` to your `lint()` test
  configuration.

**8.1**

* The [data flow analyzer](dataflow-analyzer.md.html) has been
  improved; in addition to fixing a few bugs, there are a couple of
  new convenience sub classes which makes common tasks easier to
  accomplish; see the documentation for `TargetMethodDataFlowAnalyzer`
  for example.

* The new `mavenLibrary` (and `binaryStub`) test files make it simple
  to create binary stub files in your tests, without having to perform
  compilation and check in base64 and gzip encoded test files. When
  your detector resolves references, the PSI elements you get back
  differ whether you're calling into source or into binary (jar/.class
  file) elements, so testing both (which the new test files automate
  using test modes) is helpful. More information about this is
  available in [](unit-testing.md.html).

* Lint now supports analyzing TOML files. There is a new
  Scope.TOML_FILE detectors can register an interest in, a new
  TomlScanner interface to implement for visitTomlDocument callbacks,
  etc. From a GradleScanner, you can directly resolve version catalog
  libraries via lookup methods on the GradleContext.

* Lint's “diff” output for unit test verification has been improved;
  it's now smarter about combining nearby chunks. (This should not
  break existing tests; the test infrastructure will try the older
  format as a fallback if the diffs aren't matching for the new
  format.)

* Lint contains JVM 17 bytecode. You will now need to use JDK 17+
  when compiling custom Lint checks. You should also configure
  the Kotlin compiler to target JVM 17, otherwise you may see errors
  when calling inline functions declared in Lint, UAST, or PSI.

* Lint's testing infrastructure now looks not just for test/
  but also androidTest/ and testFixtures/ to set the corresponding
  source set type on each test context.

**8.0**

* A new testmode which makes sure lint checks are all suppressible.
  It analyzes the reported error locations from the expected test
  output, and inserts suppress annotations in XML, Kotlin and Java
  files and makes sure that the corresponding warnings disappear.

**7.4**

* Annotation detectors can now specify just an annotation name instead
  of its fully qualified name in order to match *all* annotations of
  that name. For example,
  `override fun applicableAnnotations() = listOf("Nullable")`
  will match both `androidx.annotation.Nullable` and
  `org.jetbrains.annotations.Nullable`. This is used by for example
  the built-in CheckResultDetector to match many new variants of the
  `CheckReturnValue` annotations, such as the ones in mockito and in
  protobuf.

* The new AnnotationUsageTypes IMPLICIT_CONSTRUCTOR and
  IMPLICIT_CONSTRUCTOR_CALL let detectors analyzing annotations get callbacks
  when an annotated no-args constructor is invoked explicitly from a subclass
  which has an implicit constructor, or from an implicit super call in an
  explicit sub constructor. These are not included by default, so override
  isApplicableAnnotationUsage to opt in.

**7.3**

* The new AnnotationUsageType.DEFINTION now lets detectors easily check
  occurrences of an annotation in the source code. Previously,
  `visitAnnotationUsage` would only check annotated elements, not the
  annotations themselves, and to check an annotation you'd need to
  create an `UElementHandler`. See the docs for the new enum constant
  for more details, and for an example of a detector that was converted
  from a handler to using this, see `IgnoreWithoutReasonDetector`.

* Lint unit tests can now include `package-info.java` files with
  annotations in source form (until now, this only worked if the files
  were provided as binary class files)

* String replacement quickfixes can now be configured with a list of
  imports to be performed when the fix is applied. This can be used to
  for example import Kotlin extension functions needed by the
  replacement string. (You should not use this for normal imports;
  instead, the replacement string should use fully qualified names
  everywhere along with the `shortenNames` property on the fix, and
  then lint will rewrite and import all symbols that can be done
  without conflicts.)

**7.2**

* There is now a way to register “options” for detectors. These are
  simple key/value pairs of type string, integer, boolean or file, and
  users can configure values in `lint.xml` files. This has all been
  possible since 4.2, but in 7.2 there is now a way to register the
  names, descriptions and default values of these options, and these
  will show up in issue explanations, HTML reports, and so on. (In the
  future we can use this to create an Options UI in the IDE, allow
  configuration via Gradle DSL, and so on.)

  For more, see the [options chapter](options.md.html).

* A new test mode, `TestMode.CDATA`, checks that tests correctly handle
  XML CDATA sections in `<string>` declarations.

**7.1**

* Lint now bundles IntelliJ version 2021.1 and Kotlin compiler version 1.5.30.
  You may see minor API changes in these dependencies. For example,
  the Kotlin UAST class `KotlinUMethod` changed packages from
  `org.jetbrains.uast.kotlin.declarations` to `org.jetbrains.uast.kotlin`.

* The default behaviour of ResourceXmlDetector will change.
  It will skip res/raw folder and you have to override appliesTo method
  if you want your Lint checks to run there.

* The computation of checksums for binary test files (e.g. `compiled`
  and `bytecode`) unfortunately had to change; the old mechamism was
  not stable. This means that after updating some of the test files
  will show as having wrong checksums (e.g. “The checksum does not
  match for test.kt; expected 0x26e3997d but was 0xb76b5946”). In these
  cases, just drop in the new checksum.

* Source-modifying test modes. Lint's testing library now runs your
  unit tests through a number of additional paces: it will try
  inserting unnecessary parentheses, it will try replacing all
  imported symbols with fully qualified names, it will try adding
  argument names and reordering arguments to Kotlin calls, etc, and
  making sure the same results are reported. More information about
  this is available in [](test-modes.md.html).

* The support for Kotlin's overloaded operators is significantly
  improved. While these are method calls, in the AST they do not show
  up as `UCallExpressions` (instead, you'll find them as
  `UBinaryExpression`, `UPrefixExpression`, `UArrayAccessExpression`
  and so on), which meant various call-specific checks ignored them.

  Now, in addition to the built-in checks all applying to these
  implicit calls as well, lint can present these expressions as call
  expressions. This means that the `getApplicableMethodNames` machinery
  for call callbacks will now also work for overloaded functions, and
  code which is iterating through calls can use the new
  `UastCallVisitor` (or directly construct `UImplicitCallExpression`
  wrappers) to simplify processing of all these types of calls.

  Finally, lint now provides a way to resolve operators for array
  access expressions (which is missing in UAST) via the
  UArrayAccessExpression.resolveOperator extension method, which is
  also used by the above machinery.

* The annotation support (where a detector callback is invoked when
  elements are combined with annotated elements) has been significantly
  reworked (and the detector API changed). It now supports visiting
  the following additional scenarios:

  * Fields in annotated classes and packages
  * Fields and methods in annotated outerclasses
  * Class and object literals
  * Overridden methods
  * File level annotations (from Kotlin)

  It also offers better control for handling scopes -- providing all
  relevant annotations in the hierarchy at the same time such that a
  lint check for example can easily determine whether an outer
  annotation like `@Immutable` is canceled by a closer `@Mutable`
  annotation.

  There are some new annotation usage type enum constants which let
  your lint checks treat these differently. For example, the lint check
  which makes sure that calls to methods annotated with `@CheckResult`
  started flagging overrides of these methods. The fix was to add the
  following override to the `CheckResultDetector`:

  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~kotlin
  override fun isApplicableAnnotationUsage(type: AnnotationUsageType): Boolean {
    return type != AnnotationUsageType.METHOD_OVERRIDE &&
        super.isApplicableAnnotationUsage(type)
  }
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  (Using this new API constant will make your lint check only work with
  the new version of lint. An alternative fix is to check that the
  `usage` parameter is not a `UMethod`.)

  For more, see the [new documentation](annotations.md.html) for
  how to handle annotations from detectors.

* The lint testing library now contains a new test file type, `rClass`,
  which lets you easily construct Android `R` classes with resource
  declarations (which are needed in tests that reference the R fields
  to ensure that symbol resolution works.)

* When you call `context.getLocation(UMethod)`, lint will now default
  this method to be equivalent to `context.getNameLocation(UMethod)`
  instead, which will highlight the method name. This might surface
  itself as unit test failures where the location range moves from a
  single `^` into a `~~~~~` range. This is because the location printer
  uses `^` to just indicate the start offset when a range is multi-line.

**7.0**

* The API level has bumped to 10.

* Partial analysis. Lint's architecture has changed to support better
  scalability across large projects, where module results can be
  cached, etc. See the api-guide's dedicated chapter for more details.
  It is enabled by default starting in AGP 7.0.0-alpha13.

* Issue registration now takes an optional `Vendor` property, where you
  can specify information about which company or team provided this
  lint check, which library it's associated with, contact information,
  and so on. This will make it easier for users to figure out where to
  send feedback or requests for 3rd party lint checks.

* Bytecode verification: Instead of warning about 3rd party lint checks
  being obsolete because they were not compiled against the latest Lint
  API, lint now run its own bytecode verification against the lint jar
  and will silently accept older (and newer!) lint checks if they do
  not reference APIs that are not available.

* Android Lint checks can now always access the resource repository for
  random access to resources, instead of having to gather them in batch
  mode. (Previously this was only available when lint checks were
  running in the IDE.)

* The lint unit testing library now provides a `TestMode` concept. You
  can define setup and teardown methods, and lint will run unit tests
  repeatedly for each test mode. There are a number of built-in test
  modes already enabled; for example, all lint tests will run both in
  global analysis mode and in partial analysis mode, and the results
  compared to ensure they are the same.

* Lint unit tests now include source contents for secondary locations
  too. If the test fails, lint will retry without secondary source
  locations and not report an error; this preserves backwards
  compatibility.

* There's a new `Incident` class which is used to hold information to
  be reported to the user. Previously, there were a number of
  overloaded methods to report issues, taking locations, error
  messages, quick fixes, and so on. Each time we added another one we'd
  have to add another overload. Now, you instead just report incidents.
  This is critical to the new partial analysis architecture but is also
  required if you for example want to override severities per incident
  as described above.

* Lint checks can now vary the severity on a per incident basis by
  calling overrideSeverity on the incidents. This means that there is
  no longer a need to create separate issues for flavors of the same
  underlying problem with slightly different expectations around
  warnings or errors.

* There are additional modifier lookup methods for Kotlin modifiers
  on `JavaEvaluator`, like `isReified()`, `isCompanion()`,
  `isTailRec()`, and so on.

* API documentation is now available.

* UAST for Kotlin is now based on Kotlin 1.5.

* Certain Kotlin PSI elements have new implementations known as _ultra
  light classes_. Ultra light classes improve performance by answering
  PSI queries “directly from source” rather than delegating to the
  Kotlin compiler backend. You may see ultra light classes when
  accessing the `UElement.javaPsi` property of a Kotlin UAST element.
  They can also appear when resolving references. For example,
  resolving a Kotlin field reference to its declaration may result in
  an instance of `KtUltraLightFieldForSourceDeclaration`. As a
  reminder, Kotlin light classes represent the “Java view” of an
  underlying Kotlin PSI element. To access the underlying Kotlin PSI
  element you should use `UElement.sourcePsi` (preferred) or otherwise
  the extension property `PsiElement.unwrapped` (declared in
  `org.jetbrains.kotlin.asJava`).

* There is a new bug where calling `getNameIdentifier()` on Kotlin
  fields may return `null`
  ([KT-45629](https://youtrack.jetbrains.com/issue/KT-45629)).
  As a workaround you can use `JavaContext.findNameElement()` instead.

* Kotlin references to Java methods now trigger both the
  `visitMethodCall()` callback _and_ the `visitReference()` callback.
  Previously only `visitMethodCall()` was triggered.

* Quickfixes can now create and delete new files; see
  `LintFix#newFile` and `LintFix#deleteFile`..

* For quickfixes, the `independent` property had inverted logic;
  this has now been reversed to follow the meaning of the name.

* The location range returned when looking up the location for a call
  will now include arguments outside of the call range itself. This is
  important when the code is using Kotlin's assignment syntax for
  calling methods as if they are properties.

* Lint's unit testing framework now checks all `import` statements in
  test files to make sure that they resolve. This will help catch
  common bugs and misunderstandings where tests reference frameworks
  that aren't available to lint in the unit test, and where you need to
  either add the library or more commonly just add some simple stubs.
  If the import statements do not matter to the test, you can just mark
  the test as allowing compilation errors, using
  `.allowCompilationErrors()` on the `lint()` task.

* The [data flow analyzer](dataflow-analyzer.md.html) has been
  significantly improved, particularly around Kotlin scoping functions.

<!-- Markdeep: --><style class="fallback">body{visibility:hidden;white-space:pre;font-family:monospace}</style><script src="markdeep.min.js" charset="utf-8"></script><script src="https://morgan3d.github.io/markdeep/latest/markdeep.min.js" charset="utf-8"></script><script>window.alreadyProcessedMarkdeep||(document.body.style.visibility="visible")</script>
